package org.imlinker.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.ResourceBundle;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import org.imlinker.login.Account;
import org.imlinker.login.Login;

/**
 * 登录窗口.
 */

@SuppressWarnings("serial")
public class LoginWindow extends LocationSavedWindow {

	public LoginWindow(final Login paraLogin) {
		super();

		this.login = paraLogin;

		// 初始化GUI组件
		initComponents();

		// 初始化本地保存的帐号信息
		initAccounts();

		// 固定设置为屏幕居中。
		setLocationRelativeTo(null);
		setVisible(true);
	}

	/**
	 * 登录失败，更新状态栏，恢复失效的组件。
	 */
	public void loginFailed(final String info) {
		setStatus(info);

		enableInput();
	}

	/**
	 * 更新窗口底部的状态栏.
	 * 
	 * @param status
	 *            新的状态
	 */
	public void setStatus(final String status) {
		statusInfoLabel.setText(status);
	}

	private void changeUser(final Object item) {
		String user = (String) item;

		for (Account account : list) {
			if (user.startsWith(account.getUser())) {
				domainField.setText(account.getDomain());
				hostField.setText(account.getHost());
				portField.setText(account.getPort());

				String password = account.getPassword();
				passwordField.setText(password);
				if (password.trim().length() > 0) {
					checkSavePass.setEnabled(false);
					checkSavePass.setSelected(true);
					checkSavePass.setEnabled(true);
				} else {
					checkSavePass.setSelected(false);
				}
			}
		}
	}

	/**
	 * 使界面上的组件失效，进入登录状态.
	 */
	private void disableInput() {
		userBox.setEnabled(false);
		passwordField.setEnabled(false);
		loginButton.setEnabled(false);
		checkSavePass.setEnabled(false);
		hostField.setEnabled(false);
		domainField.setEnabled(false);
		portField.setEnabled(false);
	}

	/**
	 * 使登录状态时失效的组件 恢复效果，在登录失败的情况下发生.
	 */
	private void enableInput() {
		userBox.setEnabled(true);
		passwordField.setEnabled(true);
		loginButton.setEnabled(true);
		checkSavePass.setEnabled(true);
		hostField.setEnabled(true);
		domainField.setEnabled(true);
		portField.setEnabled(true);
	}

	private void initAccounts() {

		userBoxModel = new DefaultComboBoxModel();
		userBox.setModel(userBoxModel);

		list = login.getAccountList();
		int size = list.size();
		for (int i = size - 1; i >= 0; i--) {
			Account account = list.get(i);

			userBox.addItem(account.getUser());
		}

		// 有本地帐户存在的情况
		if (list.size() > 0) {
			Account account = list.get(size - 1);

			hostField.setText(account.getHost());
			domainField.setText(account.getDomain());
			portField.setText(account.getPort());

			// 密码被保存下来的情况。
			if (account.getPassword().trim().length() > 0) {
				checkSavePass.setSelected(true);
				passwordField.setText(account.getPassword());
			}
		}
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		javax.swing.JTabbedPane jTabbedPane1 = new javax.swing.JTabbedPane();
		javax.swing.JPanel jPanel1 = new javax.swing.JPanel();
		userBox = new javax.swing.JComboBox();
		javax.swing.JLabel usernameLabel = new javax.swing.JLabel();
		javax.swing.JLabel passwordLabel = new javax.swing.JLabel();
		passwordField = new javax.swing.JPasswordField();
		loginButton = new javax.swing.JButton();
		checkSavePass = new javax.swing.JCheckBox();
		javax.swing.JPanel jPanel2 = new javax.swing.JPanel();
		javax.swing.JLabel hostLabel = new javax.swing.JLabel();
		hostField = new javax.swing.JTextField();
		javax.swing.JLabel domainLabel = new javax.swing.JLabel();
		domainField = new javax.swing.JTextField();
		portLabel = new javax.swing.JLabel();
		portField = new javax.swing.JTextField();
		javax.swing.JSeparator jSeparator1 = new javax.swing.JSeparator();
		javax.swing.JLabel statusLabel = new javax.swing.JLabel();
		statusInfoLabel = new javax.swing.JLabel();

		bundle = java.util.ResourceBundle.getBundle("org/imlinker/gui/Bundle"); // NOI18N

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setTitle(bundle.getString("LoginWindow.title")); // NOI18N
		setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
		setName("LoginWindow");

		userBox.setName("userBox"); // NOI18N
		userBox.setEditable(true);
		userBox.addItemListener(new ItemListener() {

			public void itemStateChanged(ItemEvent e) {
				if (e.getStateChange() == ItemEvent.SELECTED) {
					changeUser(e.getItem());
				}
			}

		});

		usernameLabel.setText(bundle
				.getString("LoginWindow.usernameLabel.text")); // NOI18N
		usernameLabel.setName("jLabel1"); // NOI18N

		passwordLabel.setText(bundle
				.getString("LoginWindow.passwordLabel.text")); // NOI18N
		passwordLabel.setName("jLabel2"); // NOI18N

		passwordField.setName("jPasswordField1"); // NOI18N
		passwordField.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				login();
			}

		});
		passwordField.addFocusListener(new FocusAdapter() {

			public void focusGained(FocusEvent e) {
				passwordField.selectAll();
			}

		});

		loginButton.setText(bundle.getString("LoginWindow.loginButton.text")); // NOI18N
		loginButton.setName("jButton1"); // NOI18N

		loginButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {

				login();
			}

		});

		checkSavePass
				.setText(bundle.getString("LoginWindow.savePassword.text")); // NOI18N
		checkSavePass.setName("jCheckBox1"); // NOI18N
		checkSavePass.addItemListener(new ItemListener() {

			public void itemStateChanged(ItemEvent e) {
				if (!checkSavePass.isEnabled()) {
					return;
				}

				if (e.getStateChange() == ItemEvent.SELECTED) {
					int result = JOptionPane
							.showConfirmDialog(
									LoginWindow.this,
									"It is not safe to save pasword in local file.Save?",
									"SavePassword",
									JOptionPane.OK_CANCEL_OPTION);
					if (result == JOptionPane.CANCEL_OPTION) {
						checkSavePass.setSelected(false);
					}
				}
			}

		});

		javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(
				jPanel1);
		jPanel1.setLayout(jPanel1Layout);
		jPanel1Layout
				.setHorizontalGroup(jPanel1Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel1Layout
										.createSequentialGroup()
										.addGroup(
												jPanel1Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addGroup(
																jPanel1Layout
																		.createSequentialGroup()
																		.addGap(
																				19,
																				19,
																				19)
																		.addComponent(
																				passwordLabel))
														.addGroup(
																jPanel1Layout
																		.createSequentialGroup()
																		.addContainerGap()
																		.addComponent(
																				usernameLabel)))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												jPanel1Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addGroup(
																jPanel1Layout
																		.createSequentialGroup()
																		.addPreferredGap(
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent(
																				loginButton)
																		.addPreferredGap(
																				javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																		.addComponent(
																				checkSavePass))
														.addComponent(
																passwordField,
																javax.swing.GroupLayout.Alignment.TRAILING,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																321,
																Short.MAX_VALUE)
														.addComponent(userBox,
																0, 321,
																Short.MAX_VALUE))
										.addContainerGap()));
		jPanel1Layout
				.setVerticalGroup(jPanel1Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel1Layout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												jPanel1Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																usernameLabel)
														.addComponent(
																userBox,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
										.addGroup(
												jPanel1Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																passwordField,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(
																passwordLabel))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												jPanel1Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																loginButton)
														.addComponent(
																checkSavePass))
										.addGap(35, 35, 35)));

		jTabbedPane1.addTab(bundle
				.getString("LoginWindow.basicPanel.TabConstraints.tabTitle"),
				jPanel1); // NOI18N

		jPanel2.setName("jPanel2"); // NOI18N

		hostLabel.setText(bundle.getString("LoginWindow.host.text")); // NOI18N
		hostLabel.setName("jLabel6"); // NOI18N

		hostField.setName("jTextField1"); // NOI18N

		domainLabel.setText(bundle.getString("LoginWindow.domain.text")); // NOI18N
		domainLabel.setName("jLabel7"); // NOI18N

		domainField.setName("jTextField2"); // NOI18N

		portLabel.setText(bundle.getString("LoginWindow.port.text")); // NOI18N
		portLabel.setName("jLabel8"); // NOI18N

		portField.setName("jTextField3"); // NOI18N

		javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(
				jPanel2);
		jPanel2.setLayout(jPanel2Layout);
		jPanel2Layout
				.setHorizontalGroup(jPanel2Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel2Layout
										.createSequentialGroup()
										.addGap(21, 21, 21)
										.addGroup(
												jPanel2Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.TRAILING)
														.addComponent(portLabel)
														.addComponent(
																domainLabel)
														.addComponent(hostLabel))
										.addGap(18, 18, 18)
										.addGroup(
												jPanel2Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.TRAILING,
																false)
														.addComponent(portField)
														.addComponent(
																domainField)
														.addComponent(
																hostField,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																291,
																Short.MAX_VALUE))
										.addContainerGap()));
		jPanel2Layout
				.setVerticalGroup(jPanel2Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel2Layout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												jPanel2Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																hostField,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(hostLabel))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
										.addGroup(
												jPanel2Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																domainField,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(
																domainLabel))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												jPanel2Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																portField,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(portLabel))
										.addContainerGap(18, Short.MAX_VALUE)));

		jTabbedPane1
				.addTab(
						bundle
								.getString("LoginWindow.advancedPanel.TabConstraints.tabTitle"),
						jPanel2); // NOI18N

		jSeparator1.setName("jSeparator1"); // NOI18N

		statusLabel.setText(bundle.getString("LoginWindow.statusLabel.text")); // NOI18N
		statusLabel.setName("jLabel4"); // NOI18N

		statusInfoLabel
				.setText(bundle.getString("LoginWindow.statusInfo.text")); // NOI18N
		statusInfoLabel.setName("jLabel5"); // NOI18N

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGroup(
				layout.createSequentialGroup().addContainerGap().addComponent(
						jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE,
						404, Short.MAX_VALUE).addContainerGap()).addComponent(
				jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 428,
				Short.MAX_VALUE).addGroup(
				layout.createSequentialGroup().addContainerGap().addComponent(
						statusLabel).addPreferredGap(
						javax.swing.LayoutStyle.ComponentPlacement.RELATED)
						.addComponent(statusInfoLabel,
								javax.swing.GroupLayout.DEFAULT_SIZE, 359,
								Short.MAX_VALUE).addContainerGap()));
		layout
				.setVerticalGroup(layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								layout
										.createSequentialGroup()
										.addContainerGap()
										.addComponent(
												jTabbedPane1,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												166,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
										.addComponent(
												jSeparator1,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
										.addGroup(
												layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																statusLabel)
														.addComponent(
																statusInfoLabel))
										.addContainerGap()));

		pack();
	} // </editor-fold>

	/**
	 * 点击登录按钮或者在密码输入框按回车，触发的登录事件.
	 */
	private void login() {
		// 获得用户名和密码，同时判断在为空的情况下提出警告
		JTextField userField = (JTextField) userBox.getEditor()
				.getEditorComponent();
		String user = userField.getText().trim();
		if (user.length() == 0) {
			JOptionPane.showMessageDialog(this, bundle
					.getString("LoginWindow.needusername.content"), bundle
					.getString("LoginWindow.needusername.title"),
					JOptionPane.INFORMATION_MESSAGE);
			return;
		}
		String password = new String(passwordField.getPassword()).trim();
		if (password.length() == 0) {
			JOptionPane.showMessageDialog(this, bundle
					.getString("LoginWindow.needpassword.content"), bundle
					.getString("LoginWindow.needpassword.title"),
					JOptionPane.INFORMATION_MESSAGE);
			return;
		}

		// 把登录信息包装成一个Account。
		Account account = new Account();

		account.setUser(user);
		account.setPassword(new String(passwordField.getPassword()));
		account.setDomain(domainField.getText());
		account.setHost(hostField.getText());
		account.setPort(portField.getText());

		// 把Account和是否保存密码的信息提交给login线程。
		login.setAccount(account);
		login.setSaved(checkSavePass.isSelected());

		// 使界面上一些组件失效，进入登录状态
		disableInput();
	}

	// Variables declaration - do not modify
	private javax.swing.JButton loginButton;

	private javax.swing.JCheckBox checkSavePass;

	private javax.swing.JComboBox userBox;

	private DefaultComboBoxModel userBoxModel;

	private javax.swing.JLabel statusInfoLabel;

	private javax.swing.JLabel portLabel;

	private javax.swing.JPasswordField passwordField;

	private javax.swing.JTextField hostField;

	private javax.swing.JTextField domainField;

	private javax.swing.JTextField portField;

	private Login login;

	private ArrayList<Account> list;

	private ResourceBundle bundle;

	// End of variables declaration

}
